package com.luge.model.download;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;

import android.annotation.SuppressLint;
import android.os.Handler;
import android.os.Message;

@SuppressLint("HandlerLeak")
public class DownLoad {
	public static final int START = 1;
	public static final int PAUSE = 2;
	public static final int STOP = 3;

	public static final int SUCCESS = 4;
	public static final int PROGRESS = 5;
	public static final int FAIL = 6;

	private ArrayList<DownLoadCallBack> callBacks;
	private String urlPath;
	private String filePath;
	private Handler handler;
	private int downType;
	private int progress;
	private boolean progressType;

	public DownLoad(String urlPath, String filePath, boolean progressType) {
		this.urlPath = urlPath;
		this.filePath = filePath;
		this.progressType = progressType;
		this.callBacks = new ArrayList<DownLoad.DownLoadCallBack>();
	}

	public DownLoad(String urlPath, String filePath) {
		this.urlPath = urlPath;
		this.filePath = filePath;
		this.progressType = false;
		this.callBacks = new ArrayList<DownLoad.DownLoadCallBack>();
	}

	public void start() {
		this.downType = START;
		this.handler = new Handler() {
			@Override
			public void handleMessage(Message msg) {
				switch (msg.what) {
				case FAIL:
					DownLoadManager.getInstance().remove(urlPath);
					for (DownLoadCallBack callBack : callBacks) {
						callBack.fail();
					}
					break;
				case SUCCESS:
					DownLoadManager.getInstance().remove(urlPath);
					for (DownLoadCallBack callBack : callBacks) {
						callBack.success(urlPath);
					}
					break;
				case PROGRESS:
					for (DownLoadCallBack callBack : callBacks) {
						callBack.progress(progress);
					}
					break;
				default:
					break;
				}

			}
		};
		handler.sendEmptyMessage(PROGRESS);
		new Thread(new Runnable() {

			@Override
			public void run() {
				HttpURLConnection httpURLConnection = null;
				InputStream inputStream = null;
				FileOutputStream outputStream = null;
				File file = null;
				try {
					URL url = new URL(urlPath);
					httpURLConnection = (HttpURLConnection) url
							.openConnection();
					httpURLConnection.connect();
					inputStream = httpURLConnection.getInputStream();
					file = new File(filePath);
					file.createNewFile();
					outputStream = new FileOutputStream(file);
					byte[] buffer = new byte[1024];
					int size = httpURLConnection.getContentLength();
					int count = 0;
					int len = -1;
					while ((len = inputStream.read(buffer)) != -1) {
						if (downType == STOP) {
							file.delete();
							handler.sendEmptyMessage(FAIL);
							return;
						}
						outputStream.write(buffer, 0, len);
						if (progressType) {
							count += len;
							progress = count * 100 / size;
							handler.sendEmptyMessage(PROGRESS);
						}
					}
					handler.sendEmptyMessage(SUCCESS);
				} catch (Exception e) {
					e.printStackTrace();
					if (file != null) {
						file.delete();
					}
					handler.sendEmptyMessage(FAIL);
				} finally {
					try {
						if (outputStream != null) {
							outputStream.flush();
							outputStream.close();
							outputStream = null;
						}
						if (inputStream != null) {
							inputStream.close();
							inputStream = null;
						}
						if (httpURLConnection != null) {
							httpURLConnection.disconnect();
							httpURLConnection = null;
						}
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
			}
		}).start();
	}

	public int getProgress() {
		return progress;
	}

	public void stop() {
		this.downType = STOP;
	}

	public void pause() {
		this.downType = PAUSE;
	}

	public void add(DownLoadCallBack downLoadCallBack) {
		callBacks.add(downLoadCallBack);
	}

	public interface DownLoadCallBack {
		void success(String urlPath);

		void fail();

		void progress(int progress);
	}
}
